package at.fhooe.mc;


import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Random;

import org.easymock.EasyMock;
import org.easymock.IMocksControl;
import org.junit.Before;
import org.junit.Test;
import at.fhooe.mc.control.ElevatorControlCenter;
import at.fhooe.mc.control.IAdapter;
import at.fhooe.mc.control.RemoteElevatorAdapter;
import at.fhooe.mc.control.automation.SingleElevatorControlAlgorithm;
import at.fhooe.mc.data.ControlMode;
import at.fhooe.mc.data.DirectionType;
import at.fhooe.mc.data.DoorState;
import at.fhooe.mc.data.ElevatorData;
import at.fhooe.mc.data.FloorData;
import at.fhooe.mc.data.SystemData;
import at.fhooe.mc.data.control.ElevatorControlData;
import at.fhooe.mc.model.ElevatorControlCenterObserver;
import at.fhooe.mc.view.ElevatorControlCenterView;

public class ElevatorControlCenterThreadTest
{
	private ElevatorControlCenter elevatorControlCenter;
	private IAdapter mock;
	private IMocksControl mockControl;

	private ElevatorControlCenterObserver mockObserver;

	@Before
	public void setUp()
	{
		mockControl = EasyMock.createStrictControl();
		mock = mockControl.createMock(IAdapter.class);

		mockObserver = mockControl.createMock(ElevatorControlCenterObserver.class);

		elevatorControlCenter = new ElevatorControlCenter();
		elevatorControlCenter.setAdapter(new RemoteElevatorAdapter());
	}
	//==============================================================================
	@Test
	public void test100Threads() throws Exception
	{
		for (int i = 0; i < 100; i++)
		{
			assertTrue("A thread to elevator control center couldn's start",elevatorControlCenter.start());
		}
//		elevatorControlCenter.start();
	}
	//==============================================================================
	@Test
	public void testSingleThread() throws Exception
	{
		for (int i = 0; i < 100; i++)
		{
			assertTrue("",elevatorControlCenter.start());
//			ElevatorControlCenterView elevatorControlCenterView = new ElevatorControlCenterView(elevatorControlCenter);
			elevatorControlCenter.registerObserver(mockObserver);

			SystemData data = getRandonSystemData();

			elevatorControlCenter.getControlElevatorData();
			mockObserver.updateNewValues(data);

			elevatorControlCenter.doWork();
			mockObserver.wait(100);
//			mockObserver.
//			elevatorControlCenter.

			// I am trying here of test using the mock that the new values inserted in the mock affect the elevator Control center values, on a heavy 100 threads environment
		}
	}
	//==============================================================================
	private SystemData getRandonSystemData()
	{
		Random random = new Random();

		SystemData systemRandomData = new SystemData();
		systemRandomData.setClockTick(1000L);
		systemRandomData.setFloorHeight(20);

		int numFloors = random.nextInt(20);
		for (int i = 0; i < numFloors;i++)
		{
			FloorData f = new FloorData();
			f.setFloorIndex(i);
			f.setFloorButtonDown(random.nextBoolean());
			f.setFloorButtonUp(random.nextBoolean());
			systemRandomData.getFloors().add(f);
		}

		int numElevators = random.nextInt(5);

		for (int i = 0; i < numElevators;i++)
		{
			ElevatorData anElevator = new ElevatorData(numFloors,	random.nextBoolean()?ControlMode.AUTOMATIC:ControlMode.MANUAL);

			anElevator.setElevatorIndex(i);
			anElevator.setElevatorFloor(random.nextInt(numFloors));
			anElevator.setElevatorPosition(10);
			anElevator.setCurrentTarget(random.nextInt(numFloors));
			anElevator.setCommittedDirection(random.nextBoolean()?DirectionType.UP:DirectionType.DOWN);
			anElevator.setElevatorDoorStatus(random.nextBoolean()?DoorState.OPEN:DoorState.CLOSED);
			anElevator.setElevatorSpeed(23);
			anElevator.setElevatorAccel(12);
			anElevator.setElevatorCapacity(300);
			anElevator.setElevatorWeight(random.nextInt(300));

			for (int j = 0; j < numFloors;j++)
			{
				anElevator.getElevatorButton()[j] = random.nextBoolean();
				anElevator.getServicesFloors()[j] = random.nextBoolean();
			}
			systemRandomData.getElevators().add(anElevator);
		}

		return systemRandomData;
	}

}